using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using System.IO;
using Microsoft.Extensions.Primitives;

namespace RestfulApi.Controllers
{
    /// <summary>
    /// 数据绑定示例控制器 - 展示各种ASP.NET Core数据绑定方式
    /// </summary>
    [ApiController]
    [Route("api/binding")]
    [Produces("application/json")]
    public class DataBindingController : ControllerBase
    {
        /// <summary>
        /// [FromBody] 示例 - 从请求体绑定复杂类型
        /// </summary>
        /// <remarks>
        /// 请求示例:
        ///     POST /api/binding/body
        ///     Content-Type: application/json
        ///     
        ///     {
        ///        "name": "测试产品",
        ///        "price": 99.99,
        ///        "description": "这是一个测试产品"
        ///     }
        /// </remarks>
        [HttpPost("body")]
        [Consumes("application/json")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public IActionResult FromBodyExample([FromBody] ProductDto product)
        {
            if (product == null)
            {
                return BadRequest("请求体不能为空");
            }

            return Ok(new { 
                message = "成功接收数据", 
                receivedData = product 
            });
        }

        /// <summary>
        /// [FromRoute] 示例 - 从URL路由绑定参数
        /// </summary>
        /// <remarks>
        /// 请求示例:
        ///     GET /api/binding/route/123/details/active
        /// </remarks>
        [HttpGet("route/{id:int}/details/{status}")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public IActionResult FromRouteExample(
            [FromRoute] int id, 
            [FromRoute] string status)
        {
            return Ok(new { 
                message = "成功接收路由参数", 
                id = id, 
                status = status 
            });
        }

        /// <summary>
        /// [FromQuery] 示例 - 从查询字符串绑定参数
        /// </summary>
        /// <remarks>
        /// 请求示例:
        ///     GET /api/binding/query?name=测试&page=1&pageSize=10&tags=tag1&tags=tag2
        /// </remarks>
        [HttpGet("query")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public IActionResult FromQueryExample(
            [FromQuery] string name,
            [FromQuery] int page = 1,
            [FromQuery] int pageSize = 10,
            [FromQuery] string[] tags = null)
        {
            return Ok(new { 
                message = "成功接收查询参数", 
                name = name, 
                page = page, 
                pageSize = pageSize,
                tags = tags ?? Array.Empty<string>()
            });
        }

        /// <summary>
        /// [FromForm] 示例 - 从表单数据绑定参数
        /// </summary>
        /// <remarks>
        /// 请求示例:
        ///     POST /api/binding/form
        ///     Content-Type: multipart/form-data
        ///     
        ///     name=测试产品&price=99.99&inStock=true
        /// </remarks>
        [HttpPost("form")]
        [Consumes("multipart/form-data", "application/x-www-form-urlencoded")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public IActionResult FromFormExample(
            [FromForm] string name,
            [FromForm] decimal price,
            [FromForm] bool inStock)
        {
            return Ok(new { 
                message = "成功接收表单数据", 
                name = name, 
                price = price, 
                inStock = inStock 
            });
        }

        /// <summary>
        /// [FromForm] 文件上传示例 - 从表单数据绑定文件
        /// </summary>
        /// <remarks>
        /// 请求示例:
        ///     POST /api/binding/upload
        ///     Content-Type: multipart/form-data
        ///     
        ///     file=@文件路径
        ///     description=文件描述
        /// </remarks>
        [HttpPost("upload")]
        [Consumes("multipart/form-data")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> FileUploadExample(
            [FromForm] IFormFile file,
            [FromForm] string description)
        {
            if (file == null || file.Length == 0)
            {
                return BadRequest("未提供文件或文件为空");
            }

            // 获取文件信息
            var fileInfo = new {
                FileName = file.FileName,
                ContentType = file.ContentType,
                Length = file.Length,
                Description = description
            };

            // 实际应用中，这里会保存文件
            // var filePath = Path.GetTempFileName();
            // using (var stream = System.IO.File.Create(filePath))
            // {
            //     await file.CopyToAsync(stream);
            // }

            return Ok(new { 
                message = "成功接收文件", 
                fileInfo = fileInfo 
            });
        }

        /// <summary>
        /// [FromHeader] 示例 - 从HTTP头绑定参数
        /// </summary>
        /// <remarks>
        /// 请求示例:
        ///     GET /api/binding/header
        ///     X-API-Key: your-api-key
        ///     Accept-Language: zh-CN
        /// </remarks>
        [HttpGet("header")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public IActionResult FromHeaderExample(
            [FromHeader(Name = "X-API-Key")] string apiKey,
            [FromHeader(Name = "Accept-Language")] string language)
        {
            return Ok(new { 
                message = "成功接收头信息", 
                apiKey = apiKey, 
                language = language 
            });
        }

        /// <summary>
        /// 复杂模型绑定示例 - 绑定嵌套对象和集合
        /// </summary>
        /// <remarks>
        /// 请求示例:
        ///     POST /api/binding/complex
        ///     Content-Type: application/json
        ///     
        ///     {
        ///        "order": {
        ///           "id": "ORD-2023-001",
        ///           "customerName": "张三",
        ///           "orderDate": "2023-05-20T10:30:00"
        ///        },
        ///        "items": [
        ///           {
        ///              "productId": 101,
        ///              "quantity": 2,
        ///              "unitPrice": 50.00
        ///           },
        ///           {
        ///              "productId": 102,
        ///              "quantity": 1,
        ///              "unitPrice": 99.99
        ///           }
        ///        ],
        ///        "shippingAddress": {
        ///           "street": "某某路123号",
        ///           "city": "北京",
        ///           "zipCode": "100000"
        ///        }
        ///     }
        /// </remarks>
        [HttpPost("complex")]
        [Consumes("application/json")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public IActionResult ComplexBindingExample([FromBody] OrderViewModel orderViewModel)
        {
            if (orderViewModel == null)
            {
                return BadRequest("请求体不能为空");
            }

            // 计算订单总金额
            decimal total = 0;
            foreach (var item in orderViewModel.Items)
            {
                total += item.Quantity * item.UnitPrice;
            }

            return Ok(new { 
                message = "成功接收复杂数据", 
                order = orderViewModel,
                totalAmount = total
            });
        }

        /// <summary>
        /// 混合绑定示例 - 同时使用多种绑定源
        /// </summary>
        /// <remarks>
        /// 请求示例:
        ///     PUT /api/binding/mixed/123?version=2
        ///     X-Tracking-Id: ABC-123-XYZ
        ///     Content-Type: application/json
        ///     
        ///     {
        ///        "name": "更新的产品",
        ///        "price": 88.88
        ///     }
        /// </remarks>
        [HttpPut("mixed/{id}")]
        [Consumes("application/json")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public IActionResult MixedBindingExample(
            [FromRoute] int id,
            [FromQuery] int version,
            [FromHeader(Name = "X-Tracking-Id")] string trackingId,
            [FromBody] ProductUpdateDto product)
        {
            return Ok(new { 
                message = "成功接收混合绑定数据", 
                id = id,
                version = version,
                trackingId = trackingId,
                product = product
            });
        }

        /// <summary>
        /// 自定义模型绑定示例 - 使用[ModelBinder]特性
        /// </summary>
        /// <remarks>
        /// 在实际应用中，你可以创建自定义的IModelBinder实现
        /// 这里仅作为示例，展示如何使用[ModelBinder]特性
        /// </remarks>
        [HttpGet("custom")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public IActionResult CustomBindingExample(
            [ModelBinder(Name = "dateRange")] DateRange dateRange)
        {
            // 注意：这个示例需要实现自定义的DateRangeModelBinder
            // 这里简化处理，直接返回一个模拟的日期范围
            var range = new DateRange
            {
                StartDate = DateTime.Now.AddDays(-7),
                EndDate = DateTime.Now
            };

            return Ok(new { 
                message = "自定义模型绑定示例", 
                dateRange = range
            });
        }

        /// <summary>
        /// 原始请求访问示例 - 直接访问请求对象
        /// </summary>
        [HttpPost("raw")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public IActionResult RawRequestExample()
        {
            // 直接访问请求对象
            var method = Request.Method;
            var path = Request.Path;
            var queryString = Request.QueryString;
            var headers = Request.Headers;
            var cookies = Request.Cookies;
            
            // 读取请求体（在实际应用中需要更复杂的处理）
            Request.EnableBuffering();
            using var reader = new StreamReader(Request.Body, leaveOpen: true);
            Request.Body.Position = 0;
            var body = reader.ReadToEndAsync().Result;
            Request.Body.Position = 0;

            return Ok(new { 
                message = "原始请求访问示例", 
                method = method,
                path = path.ToString(),
                queryString = queryString.ToString(),
                headerCount = headers.Count,
                cookieCount = cookies.Count,
                bodyPreview = body.Length > 100 ? body.Substring(0, 100) + "..." : body
            });
        }
    }

    #region 数据传输对象

    /// <summary>
    /// 产品数据传输对象
    /// </summary>
    public class ProductDto
    {
        /// <summary>
        /// 产品名称
        /// </summary>
        [Required(ErrorMessage = "产品名称不能为空")]
        [StringLength(100, ErrorMessage = "产品名称不能超过100个字符")]
        public string Name { get; set; }

        /// <summary>
        /// 产品价格
        /// </summary>
        [Range(0.01, 9999999, ErrorMessage = "价格必须大于0且小于1000万")]
        public decimal Price { get; set; }

        /// <summary>
        /// 产品描述
        /// </summary>
        public string Description { get; set; }
    }

    /// <summary>
    /// 产品更新数据传输对象
    /// </summary>
    public class ProductUpdateDto
    {
        /// <summary>
        /// 产品名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 产品价格
        /// </summary>
        public decimal Price { get; set; }
    }

    /// <summary>
    /// 订单视图模型
    /// </summary>
    public class OrderViewModel
    {
        /// <summary>
        /// 订单基本信息
        /// </summary>
        [Required]
        public OrderInfo Order { get; set; }

        /// <summary>
        /// 订单项列表
        /// </summary>
        [Required]
        [MinLength(1, ErrorMessage = "订单必须至少包含一个商品")]
        public List<OrderItem> Items { get; set; }

        /// <summary>
        /// 配送地址
        /// </summary>
        [Required]
        public Address ShippingAddress { get; set; }
    }

    /// <summary>
    /// 订单信息
    /// </summary>
    public class OrderInfo
    {
        /// <summary>
        /// 订单ID
        /// </summary>
        public string Id { get; set; }

        /// <summary>
        /// 客户名称
        /// </summary>
        public string CustomerName { get; set; }

        /// <summary>
        /// 订单日期
        /// </summary>
        public DateTime OrderDate { get; set; }
    }

    /// <summary>
    /// 订单项
    /// </summary>
    public class OrderItem
    {
        /// <summary>
        /// 产品ID
        /// </summary>
        public int ProductId { get; set; }

        /// <summary>
        /// 数量
        /// </summary>
        [Range(1, 100, ErrorMessage = "数量必须在1-100之间")]
        public int Quantity { get; set; }

        /// <summary>
        /// 单价
        /// </summary>
        [Range(0.01, 9999999, ErrorMessage = "单价必须大于0")]
        public decimal UnitPrice { get; set; }
    }

    /// <summary>
    /// 地址
    /// </summary>
    public class Address
    {
        /// <summary>
        /// 街道
        /// </summary>
        public string Street { get; set; }

        /// <summary>
        /// 城市
        /// </summary>
        public string City { get; set; }

        /// <summary>
        /// 邮政编码
        /// </summary>
        public string ZipCode { get; set; }
    }

    /// <summary>
    /// 日期范围
    /// </summary>
    public class DateRange
    {
        /// <summary>
        /// 开始日期
        /// </summary>
        public DateTime StartDate { get; set; }

        /// <summary>
        /// 结束日期
        /// </summary>
        public DateTime EndDate { get; set; }
    }

    #endregion
}